home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 October: Mac OS SDK / Dev.CD Oct 96 SDK / Dev.CD Oct 96 SDK2.toast / Development Kits (Disc 2) / OpenDoc Development Framework / Documentation / Engineering Notes / Views / Scrolling < prev    next >
Encoding:
Text File  |  1996-08-16  |  9.7 KB  |  203 lines  |  [TEXT/ttxt]

  1. OpenDoc
  2. Development
  3. Framework
  4.                                                                                                                                                                                      
  5. Scrolling 
  6. ODF Release 1                                                                                                                                                             
  7.  
  8.  
  9. Table of Content
  10. ---------------------
  11. • Using ODF Scroller Classes
  12.     • Adding a Scroller to Your Frame
  13.     • Handling Scroll Notifications
  14. • Auto Scrolling
  15.     • Two-step API
  16.     • One-step API
  17.  
  18.  
  19. Using ODF Scroller Classes
  20.  
  21. ODF provides 2 classes, FW_CScroller and FW_CScrollbarScroller to implement scrolling of your frame's content view.  FW_CScrollbarScroller derives from FW_CScroller  adding one or two scroll bars.  Because the scroller relies on the frame's internal transform (which represents the position of your content inside the frame) it can only be used with the content view and there can be only one instance of this type in each frame.
  22.  
  23. Notes:
  24.  
  25. • A future version of ODF will support a more generic "view scroller" independent of the internal transform  that lets you scroll any view.   To implement scrolling in edit views please see the CScrollEdit class provided as an example in Form. 
  26.  
  27. • If you need more than one scroller in your frame it means that you need more than one content view, in which case you must use embedded frames as UI elements.
  28.  
  29. Adding a Scroller to Your Frame
  30.  
  31. The easiest way is to define the scroller in resources along with the frame's views.  For a scroll bar scroller you must have defined the scroll bar views earlier in the list of subviews in order to reference their view ids.  Here is a typical frame layout resource:
  32.  
  33. resource FW_RFrameLayout(kMyFrameView)
  34. {
  35.       {H,V},                              // LayoutSize
  36.       {                                      // Start list of frame's subviews
  37.  
  38.       ...               // other views
  39.  
  40.             FW_RScrollBar          // Horizontal scroll bar
  41.             (
  42.                   kHorzScrollBarID,                                      // view id
  43.                   {-FW_ONE, V - FW_SBSIZE, H1 - FW_SBSIZE, V1},    //  bounds 
  44.          ...
  45.       ),
  46.          FW_RScrollBar          // Vertical scroll bar
  47.             (
  48.                    kVertScrollBarID,                                      // view id
  49.                    {H - FW_SBSIZE, -FW_ONE, H1, V1 - FW_SBSIZE},    // bounds 
  50.           ...
  51.       )
  52.        },                                       // End list of frame's subviews
  53.  
  54.        {                                     // Scroller resource comes at the end
  55.           FW_RScrollBarScroller
  56.              (
  57.                    0,                                          // AutoScrollInset: not used here
  58.                    {0, 0}                                   // AutoScrollIncrement: 0 = no auto-scroll 
  59.                    kHorzScrollBarID,               // Horizontal scroll-bar ID
  60.                    kVertScrollBarID                // Vertical scroll-bar ID
  61.              )
  62.     }
  63. };
  64.  
  65. If you don't use view resources you should create the scroll bar scroller at the end of your frame's CreateSubViews method, after having created the scroll bars and the content view.  Then the new scroller is connected using the frame's AdoptScroller method:
  66.  
  67. void CMyFrame::CreateSubViews(Environment* ev)
  68. {
  69.    ...
  70.       // ----- Create the vertical & horizontal scroll bars inside the frame
  71.    FW_CScrollBar* vertSB = FW_NEW(FW_CScrollBar, (ev, this, 0, vertSbRect));
  72.          FW_CScrollBar* horzSB = FW_NEW(FW_CScrollBar, (ev, this, 0,horzSbRect));        
  73.  
  74.       // ----- Create the content view 
  75.    ...
  76.  
  77.       // ----- Create a scroll bar scroller  (this must be done after the content view)
  78.       FW_CScroller* scroller = FW_NEW(FW_CScrollBarScroller, (ev, this, horzSB, vertSB));
  79.       AdoptScroller(ev, scroller);
  80.    ...
  81.  
  82. Important Notes:
  83.  
  84. • A scroller is deleted automatically by its frame.
  85.  
  86. • AdoptScroller will throw an exception if you use a scroll bar scroller inside a frame that is its own content view because the scroll bars would end up moving with the rest of the content!  A frame that doesn't have a separate content view can only use a basic FW_CScroller instance and can be scrolled with a hand-scrolling or auto-scrolling mechanism.
  87.  
  88. Handling Scroll Notifications
  89.  
  90. Once the scroller is created your part has nothing else to do but draw its content correctly in the content view coordinates.  Internally the scroll bars send FW_kScrollMsg notifications to the scroller and everything is taken care of by ODF.
  91.  
  92.  
  93. Auto Scrolling
  94.  
  95. Auto scrolling of the frame's content view is demonstrated in the Draw and Container samples.  It is implemented by the class FW_CScroller with the following API:
  96.  
  97. void                        SetAutoScrollIncrement(Environment* ev, const FW_CPoint& increment);
  98.  
  99. Set the auto-scrolling  increment in point, i.e. the x, y values by which the scroller will scroll the content when ScrollBy or AutoScroll is called. The default is zero which means no auto-scrolling. You must call this method to turn auto scrolling on.  If you created your views in resources you can also set the AutoScrollIncrement field  in the FW_RScroller or FW_RScrollBarScroller resources (see above).
  100.  
  101. void                        SetAutoScrollInset(Environment* ev, FW_Fixed inset);
  102.                                                 
  103.     Set the auto-scroll insert, i.e. the distance from the edge of the content view where auto-scroll will occur. The default value is 15 points.   If you created your views in resources you can also set the AutoScrollInset field  in the FW_RScroller or FW_RScrollBarScroller resources.
  104.  
  105. FW_CPoint    AutoScrollOffset(Environment* ev,    
  106.                            const FW_CPoint& currentPoint,
  107.                            unsigned long delay = 0);
  108.  
  109. Returns the auto-scroll offset, i.e. the x,y values measuring the distance of the current point from the edge of the content view (currentPoint is in content coordinates; in absolute values we have   (1,1) <= offset <= increment).   Normally  you pass this offset to ScrollBy to perform the actual scrolling.  An offset equal to FW_kZeroPoint means that the current point is outside of the auto-scrolling area defined by the scrolling inset, no scrolling should occur.  
  110.  
  111. The optional delay parameter allows to implement a delay in ticks between each scrolling operation to make the scrolling speed independent of the CPU speed n (1 tick is about 1/60 second) .  AutoScrollOffset returns a zero offset until the delay expires.
  112.  
  113. void                        ScrollBy(Environment* ev, const FW_CPoint& offset, 
  114.                                                                                 FW_CGraphicContext* gc = NULL);
  115.  
  116. Scrolls the content view by the given offset.  ScrollBy can take an extra argument, gc,  a graphic context which will be adjusted to reflect the new frame internal transform.  This is useful if you need to perform some drawing during auto scrolling.   See a code example below.
  117.  
  118. Warning: ScrollBy does not make any checking on the offset. Be sure to always call it with a valid offset (like the one returned by AutoScrollOffset).
  119.  
  120. void                     AutoScroll(Environment* ev, const FW_CPoint& currentPoint, 
  121.                                                                                     FW_GraphicContext* gc = NULL,
  122.                      unsigned long delay = 0);
  123.  
  124. AutoScroll calls AutoScrollOffset and then ScrollBy giving you a one step API.  The current point is in content coordinates.  See a code example below.
  125.  
  126. The optional delay parameter allows to implement a delay in ticks  between each scrolling operation  to make the scrolling speed independent of the CPU speed (1 tick is about 1/60 second).
  127.  
  128. void                     InitializeAutoScroll(Environment* ev);
  129.  
  130. If you use a scrolling delay you must call InitializeAutoScroll at the beginning of your tracking operation, usually in CMyTracker::BeginTracking(). 
  131.  
  132.  
  133. Two-Step API
  134.  
  135. The first method is to call  AutoScrollOffset()  followed by ScrollBy()  as in FW_CDropTracker:
  136.  
  137. FW_CPoint FW_CDropTracker::ContinueTracking(Environment* ev,
  138.                                                                                                     const FW_CPoint& anchorPoint, 
  139.                                                                                                     const FW_CPoint& previousPoint, 
  140.                                                                                                     const FW_CPoint& currentPoint)
  141. {
  142.   // Get the offset
  143.      FW_CPoint autoScrollOffset = fScroller->AutoScrollOffset(ev, currentPoint); 
  144.  
  145.      if (autoScrollOffset != FW_kZeroPoint)
  146.      {
  147.             FW_Boolean hiliteOn = fMacHiliteOn;
  148.             if (hiliteOn)
  149.                    this->HideDragHilite(ev); // turn off  hilite while scrolling
  150.         
  151.       // perform scrolling.  Extra gc argument is not needed here
  152.             fScroller->ScrollBy(ev, autoScrollOffset);
  153.         
  154.             if (hiliteOn) 
  155.             {
  156.          // Turn hilite back on
  157.                   FW_CAcquiredODShape aqHiliteShape = GetView(ev)->GetFrame(ev)->
  158.                         GetDroppable(ev)->AcquireDragHiliteShape(ev, GetFacet(ev));
  159.                   this->ShowDragHilite(ev, aqHiliteShape, TRUE);
  160.             }
  161.      }    
  162.      return currentPoint;
  163. }
  164.  
  165.  
  166. One-step API
  167.  
  168. The second method is to call  AutoScroll() directly as in ODF Draw's  CShapeTracker::ContinueTracking:
  169.  
  170. FW_CPoint CShapeTracker::ContinueTracking(Environment* ev,
  171.                                                                                                                                                                         const FW_CPoint& anchorPoint, 
  172.                                                                                                                                                                         const FW_CPoint& previousPoint, 
  173.                                                                                                                                                                         const FW_CPoint& currentPoint)
  174. {
  175.             FW_CPoint curLoc(currentPoint);
  176.     
  177.             ForceToGrid(ev, curLoc);
  178.     
  179.             if (previousPoint != curLoc)
  180.             {
  181.       // Create a view context needed by TrackFeedback()
  182.                         FW_CViewContext vc(ev, GetView(ev), GetFacet(ev));        
  183.         
  184.       // Erase the previous tracking feedback
  185.                         if (fErase)
  186.                                     fShape->TrackFeedback(ev, GetFacet(ev), vc, anchorPoint, previousPoint, TRUE); 
  187.  
  188.       // Perform scrolling and update the view context
  189.                         fScroller->AutoScroll(ev, currentPoint, &vc);
  190.  
  191.       // Redraw the tracking feedback in the correct context
  192.                         fShape->TrackFeedback(ev, GetFacet(ev), vc, anchorPoint, curLoc, FALSE);
  193.         
  194.                         fErase = TRUE;
  195.             }
  196.     
  197.             return curLoc;
  198. }
  199.  
  200.  
  201.  
  202. © 1993 - 1996 Apple Computer, Inc. All rights reserved.
  203. Apple, the Apple Logo, Macintosh, and OpenDoc are trademarks of Apple Computer, Inc., registered in the United States and other countries.